<?php


/**
 * 简单的继承了redis，增加了锁的简单接口。从概率上来说，这个是存在无效的。
 */
 
class RedisDriver {

	private $readHandle = null;
	private $writeHandle = null;
	private $pevent = null;

	public function __construct($host, $port, $pevent) {
		$this->readHandle = $this->writeHandle =  new Redis();
		$this->writeHandle->connect($host, $port);
		$this->writeHandle->auth('hongshaojichibang--');
		$this->pevent = $pevent . ':';
	}	

	public function __call($method, array $args) {
		$key = $this->pevent . array_shift($args);

		switch (count($args)) {
			case 0:
				return $this->writeHandle->$method($key);
				break;

			case 1:
				return $this->writeHandle->$method($key, $args[0]);
				break;

			case 2:
				return $this->writeHandle->$method($key, $args[0], $args[1]);
				break;

			case 3:
				return $this->writeHandle->$method($key, $args[0], $args[1], $args[2]);
				break;
			
			case 4:
				return $this->writeHandle->$method($key, $args[0], $args[1], $args[2], $args[3]);
				break;

			default:
				echo $method . '参数过多';
				break;
		}
		
		/*foreach ($args as $arg) {
			if(!is_array($arg)) {
				$value .= $arg . ',';
			}
			else {
				$value .= var_export($arg, true) . ',';
			}
		}

		$rs .= rtrim($value, ',') . ')';
		eval("$rs;");*/
	}

	public function sUnion()
	{
		$paramNum = func_num_args();

		switch ($paramNum) {
			case 2:
				return $this->writeHandle->sUnion($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1));
				break;

			case 3:
				return $this->writeHandle->sUnion($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1), $this->pevent . func_get_arg(2));
				break;

			case 4:
				return $this->writeHandle->sUnion($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1), $this->pevent . func_get_arg(2), $this->pevent . func_get_arg(3));
				break;
			
			default:
				echo 'sUnion参数过多';
				break;
		}
	}

	public function sUnionStore()
	{
		$paramNum = func_num_args();

		switch ($paramNum) {
			case 2:
				return $this->writeHandle->sUnionStore($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1));
				break;

			case 3:
				return $this->writeHandle->sUnionStore($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1), $this->pevent . func_get_arg(2));
				break;

			case 4:
				return $this->writeHandle->sUnionStore($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1), $this->pevent . func_get_arg(2), $this->pevent . func_get_arg(3));
				break;
			
			default:
				echo 'sUnionStore参数过多';
				break;
		}
	}

	public function sMove()
	{
		$paramNum = func_num_args();

		switch ($paramNum) {
			case 3:
				return $this->writeHandle->sMove($this->pevent . func_get_arg(0), $this->pevent . func_get_arg(1), func_get_arg(2));
				break;

			default:
				echo 'sMove参数错误';
				break;
		}
	}
	
	private $prefix = 'lock_';

	public function lock($key){
		if(!$this->exists($this->prefix.$key)){
			$this->set($this->prefix.$key,time());
			return true;
		}
		return false;
	}
	public function unlock($key){
		if($this->exists($this->prefix.$key)){
			$this->delete($this->prefix.$key);
			return true;
		}
		return false;		
	}
	
	/**
	 * 函数功能：保存数据到redis 以Hash的形式存储  封装$this->hmset方法
	 * @param string $block_key //redis数据存储中key对应的一个存储区域，在这里我们约定叫做数据块.每个数据块对应一个块id 
	 *  						//$block_key格式 xxx::xxx::xxxxx
	 * @param array array($key=>$val,$key2=>$val2,....)//块中元素id=>块中元素值
	 */
	public function hmSave($block_key,$kval){
		// n_state($type, $msg);
		//参数验证
		if (empty($block_key)) {
			return array(0,'redis块id不能为空');
		}
		if (empty($kval) || !is_array($kval)) {
			return array(0,'参数2只能为非空数组');
		}
		
		//块元素json编码
		if (!empty($kval)) {
			foreach ($kval as $k => $v) {
				$kval[$k] = json_encode($v);
			}
		}
		
		//同时将多个field - value(域-值)对设置到哈希表key中
		$this->hmset($block_key,$kval);
		
		return array(1,'添加成功');
	}
	
	/**
	 * 函数功能：返回哈希表key中给定域field的值  封装$this->hMget
	 * @param string $block_key //redis数据存储中key对应的一个存储区域，在这里我们约定叫做数据块.每个数据块对应一个块id 
	 *  						//$block_key格式 xxx::xxx::xxxxx
	 * @param array array($key,$key2,....)//块中元素id=>块中元素值
	 * 
	 * @return array or false
	 */
	public function hmGetElment($block_key,$key){
		//参数验证
		if (empty($block_key)) {
			return array(0,'redis块id不能为空');
		}
		if (empty($key) || !is_array($key)) {
			return array(0,'参数2只能为非空数组');
		}
		
		$arr_element = $this->hMget($block_key,$key);
		if (!empty($arr_element)) {
			foreach ($arr_element as $key => $value) {
				if (!empty($arr_element[$key])) {
					$arr_element[$key] = json_decode($value,true);
				}					
			}
		}
		return $arr_element;
	}
	
	/**
	 * 函数功能：返回哈希表key中，所有的域和值。
	 * @param string $block_key
	 */
	public function hmGetAll($block_key){
		//参数验证
		if (empty($block_key)) {
			return array(0,'redis块id不能为空');
		}

		$arr_block = $this->hGetAll($block_key);

		if (!empty($arr_block)) {
			foreach ($arr_block as $key => $value) {
				$arr_block[$key] = json_decode($value,true);
			}
		}
		
		return $arr_block;
	}
	
	/**
	 * 函数功能：删除哈希表key中的一个或多个指定域，不存在的域将被忽略
	 * @param string $block_key //redis数据存储中key对应的一个存储区域，在这里我们约定叫做数据块.每个数据块对应一个块id 
	 *  						//$block_key格式 xxx::xxx::xxxxx
	 * @param string $key 块中元素id
	 */
	public function hmDelete($block_key,$key){
		//参数验证
		if (empty($block_key)) {
			return array(0,'redis块id不能为空');
		}
		if (empty($key)) {
			return array(0,'参数2不能为空');
		}
		
		return $this->hDel($block_key,$key);
	}

	/**
	 * 函数功能：删除多个 Redis2.4以上版本
	 * @param string $block_key //redis数据存储中key对应的一个存储区域，在这里我们约定叫做数据块.每个数据块对应一个块id 
	 *  						//$block_key格式 xxx::xxx::xxxxx
	 * @param array array($key,$key2,....)//块中元素id=>块中元素值
	 */
	public function hmDeletes($block_key,$key){
		// n_state($type, $msg);
		//参数验证
		if (empty($block_key)) {
			return array(0,'redis块id不能为空');
		}
		if (empty($key) || !is_array($key)) {
			return array(0,'参数2只能为非空数组');
		}
		
		
		var_dump($this->hDel($block_key,$key));
		return array(1,'删除成功');
	}
	
	
		
	/**
	 * 娓呴櫎鐩戞帶骞冲彴鐨剆ession鐢ㄦ埛鏁版嵁
	 */
	public function clearSession(){
		$block_key = 'manager::session::ukey';
		$ret = $this->del($block_key);
		var_dump($ret);
	}
	
	/**
	 * 清除用户redis缓存
	 */
	public function clearUserCache(){
		$block_key = 'manager::user::list';
		$ret = $this->del($block_key);
		var_dump($ret);
	}
}
